package com.xci.core.aspect;


import com.xci.core.annotation.Log;
import com.xci.core.async.AsyncManager;
import com.xci.core.domain.LogInfo;
import com.xci.core.helper.Helper;
import com.xci.core.helper.SpringHelper;
import com.xci.core.helper.WebHelper;
import com.xci.core.internal.Sys;
import com.xci.sys.entity.SysOperateLog;
import com.xci.sys.service.OperateLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

/**
 * 日志记录拦截器
 *
 * @author lvyanyang
 */
@Slf4j
@Aspect
@Component
public class LogAspect {
    private ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();

    @Pointcut("@annotation(com.xci.core.annotation.Log)")
    public void executeLogPointcut() {
    }

    @Before("executeLogPointcut()")
    public void doBefore(JoinPoint joinPoint) {
        startTimeThreadLocal.set(System.currentTimeMillis());
    }

    @AfterReturning(pointcut = "executeLogPointcut()", returning = "rvt")
    public void doAfterReturning(JoinPoint joinPoint, Object rvt) {
        HttpServletRequest request = WebHelper.getRequest();
        if (request == null) {
            return;
        }
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Log log = method.getAnnotation(Log.class);

        Map<String, Object> params = new HashMap<>();
        long usedTime = System.currentTimeMillis() - startTimeThreadLocal.get();

        // 设置方法名称
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        // //返回值
        // String resultStr = Constants.EMPTY;
        // if (rvt != null) {
        //    resultStr = JsonHelper.serialize(rvt);
        // }

        LogInfo logInfo = LogInfo.builder().module(log.module())
                .method(Helper.format("{}.{}", className, methodName))
                .status(true).costTime(usedTime).msg(log.msg()).build();
        AsyncManager.me().execute(saveLog(logInfo));
    }

    public TimerTask saveLog(final LogInfo logInfo) {
        SysOperateLog operateLog = Sys.me().buildOperateLog(logInfo);
        return new TimerTask() {
            @Override
            public void run() {
                SpringHelper.getBean(OperateLogService.class).insert(operateLog);
            }
        };
    }
}